/**********************************************************************************
// Background Source
// 
// Creation:	01 Mai 2011
// Updated:		01 Mai 2011
// Compiler:	Visual Studio 2010
//
// Notes:		Defines a background image handler
//				The background does not support transparency
//
**********************************************************************************/

#include "Background.h"
#include "D3DGame.h"

/**********************************************************************************/


Background::Background(char * filename, Color colorKey)
{
	// clean the structure
	D3DXIMAGE_INFO imgInfo;
	ZeroMemory(&imgInfo, sizeof(imgInfo));

	// get image info from file
	D3DXGetImageInfoFromFile(filename, &imgInfo);

	width = imgInfo.Width;
	height = imgInfo.Height;

	// create surface with the size of the image
	D3DGame::GetDevice()->CreateOffscreenPlainSurface(
		imgInfo.Width,			// width of the surface
        imgInfo.Height,			// height of the surface
        D3DFMT_X8R8G8B8,		// surface format
        D3DPOOL_DEFAULT,		// memory pool to use
        &background,			// pointer to the surface
        NULL);					// reserved (always NULL)
	
	D3DXLoadSurfaceFromFile(
        background,             // destination surface
        NULL,                   // destination palette
        NULL,                   // destination rectangle
        filename,				// source filename
        NULL,                   // source rectangle
        D3DX_DEFAULT,           // control how image is filtered
		colorKey.Direct3D(),	// for transparency (0 for none)
        NULL);                  // source image info (usually NULL)
}

/**********************************************************************************/

Background::Background(char * filename, uint tileWidth, uint tileHeight, uint numColumns, 
		int * tileMap, uint tileMapCols, uint tileMapRows, Color colorKey)
{
	width = tileMapCols * tileWidth;
	height = tileMapRows * tileHeight;

	// create surface with the size of the image
	D3DGame::GetDevice()->CreateOffscreenPlainSurface(
		width,					// width of the surface
        height,					// height of the surface
        D3DFMT_X8R8G8B8,		// surface format
        D3DPOOL_DEFAULT,		// memory pool to use
        &background,			// pointer to the surface
        NULL);					// reserved (always NULL)
	
	// ========================================
	// Load source tiles into temporary surface
	// ========================================
	
	LPDIRECT3DSURFACE9 tiles;

	// clean the structure
	D3DXIMAGE_INFO imgInfo;
	ZeroMemory(&imgInfo, sizeof(imgInfo));

	// get image info from file
	D3DXGetImageInfoFromFile(filename, &imgInfo);

	// create surface with the size of the tile
	D3DGame::GetDevice()->CreateOffscreenPlainSurface(
		imgInfo.Width,			// width of the surface
        imgInfo.Height,			// height of the surface
        D3DFMT_X8R8G8B8,		// surface format
        D3DPOOL_DEFAULT,		// memory pool to use
        &tiles,					// pointer to the surface
        NULL);					// reserved (always NULL)
	
	D3DXLoadSurfaceFromFile(
        tiles,					// destination surface
        NULL,                   // destination palette
        NULL,                   // destination rectangle
        filename,				// source filename
        NULL,                   // source rectangle
        D3DX_DEFAULT,           // control how image is filtered
		colorKey.Direct3D(),	// for transparency (0 for none)
        NULL);                  // source image info (usually NULL)

	// ========================================

	// draw tileMap into background
	for (uint j=0; j < tileMapRows; ++j)
	{
		for (uint i=0; i < tileMapCols; ++i)
		{
			// tileMap indexes generated by Tiled app start with 1
			// tiled image indexes start with 0
			// that's why we need to subtract one from tileNum
			uint tileNum = tileMap[i + j * tileMapCols] - 1;
			RECT sourceRect = 
			{
				(tileNum % numColumns) * tileWidth,
				(tileNum / numColumns) * tileHeight, 
				sourceRect.left + tileWidth,
				sourceRect.top + tileHeight
			};
			RECT destRect =
			{
				i * tileWidth,
				j * tileHeight,
				destRect.left + tileWidth,
				destRect.top + tileHeight
			};

			D3DGame::GetDevice()->StretchRect(tiles, &sourceRect, background, &destRect, D3DTEXF_NONE);
		}
	}

	// tiles are not needed anymore
	tiles->Release();
}

/**********************************************************************************/

Background::~Background()
{
	if (background)
		background->Release();
}

/**********************************************************************************/

void Background::Draw(RECT & sourceRect)
{ 
    // draw the source surface onto the dest
	D3DGame::GetDevice()->StretchRect(
		background, &sourceRect, D3DGame::GetBackBuffer(), nullptr, D3DTEXF_NONE);
}

/**********************************************************************************/

